<!DOCTYPE html><html><head><title>React中的Context API</title><meta charset='utf-8'><link href='https://cdn.maxiang.io/res-min/themes/marxico.css' rel='stylesheet'><style>
.note-content  {font-family: 'Helvetica Neue', Arial, 'Hiragino Sans GB', STHeiti, 'Microsoft YaHei', 'WenQuanYi Micro Hei', SimSun, Song, sans-serif;}

</style></head><body><div id='preview-contents' class='note-content'>
                        
                    



<h3 id="react中的context-api">React中的Context API</h3>

<p><a href="https://zh-hans.reactjs.org/docs/context.html" target="_blank">https://zh-hans.reactjs.org/docs/context.html</a></p>

<ul><li><p>React.createContext</p></li>
<li><p>Context.Provider   =&gt; 设置vaue={}</p></li>
<li><p>Class.contextType =&gt; 获取context</p></li>
<li><p>Context.Consumer =&gt;同样为获取，基于 value=&gt;{…} 获取</p></li>
</ul>



<h3 id="基于purecomponent进行性能优化">基于PureComponent进行性能优化</h3>

<ul><li><p>在状态或者属性没有任何更新变化的时候，不渲染组件（帮助我们实现了 shouldComponentUpdate）</p></li>
<li><p>浅比较（shallowEqual）</p></li>
<li><p>对于深层次状态或者属性改变，我们尽可能重新赋值新值（或者forceUpdate）</p></li>
<li><p>PureComponent的最好作为展示组件</p></li>
<li><p>若有shouldComponentUpdate，则执行它，若没有这个方法会判断是不是PureComponent，若是，进行浅比较</p></li>
</ul>



<h3 id="react-hook">React Hook</h3>

<ul><li><p>useState</p></li>
</ul>



<pre class="prettyprint with-line-number hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-comment line-number">1.</span><span class="hljs-keyword">import</span> {useState} <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
</div><div class="hljs-line"><span class="hljs-comment line-number">2.</span><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Count</span>(<span class="hljs-params"></span>) </span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">3.</span>  <span class="hljs-keyword">var</span> [state, setState] = useState(<span class="hljs-number">0</span>);
</div><div class="hljs-line"><span class="hljs-comment line-number">4.</span>  OR
</div><div class="hljs-line"><span class="hljs-comment line-number">5.</span>  <span class="hljs-keyword">var</span> [state, setState] = useState(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">6.</span>      <span class="hljs-comment">//=&gt;惰性初始化</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">7.</span>      <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
</div><div class="hljs-line"><span class="hljs-comment line-number">8.</span>  });
</div><div class="hljs-line"><span class="hljs-comment line-number">9.</span>  <span class="hljs-keyword">return</span> (
</div><div class="hljs-line"><span class="hljs-comment line-number">10.</span>    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span>
</div><div class="hljs-line"><span class="hljs-comment line-number">11.</span><span class="xml">      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{state}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
</div><div class="hljs-line"><span class="hljs-comment line-number">12.</span><span class="xml">      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> { setState(state + 1) }}&gt;点击<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
</div><div class="hljs-line"><span class="hljs-comment line-number">13.</span><span class="xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
</div><div class="hljs-line"><span class="hljs-comment line-number">14.</span>  );
</div><div class="hljs-line"><span class="hljs-comment line-number">15.</span>}
</div></code></pre>

<p>原理：</p>



<pre class="prettyprint with-line-number hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-comment line-number">1.</span><span class="hljs-keyword">var</span> _state;
</div><div class="hljs-line"><span class="hljs-comment line-number">2.</span><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">useState</span>(<span class="hljs-params">initialState</span>) </span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">3.</span>  _state = _state | initialState;
</div><div class="hljs-line"><span class="hljs-comment line-number">4.</span>  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setState</span>(<span class="hljs-params">state</span>) </span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">5.</span>    _state = state;
</div><div class="hljs-line"><span class="hljs-comment line-number">6.</span>    <span class="hljs-comment">//...重新渲染组件</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">7.</span>  }
</div><div class="hljs-line"><span class="hljs-comment line-number">8.</span>  <span class="hljs-keyword">return</span> [_state, setState];
</div><div class="hljs-line"><span class="hljs-comment line-number">9.</span>}
</div></code></pre>

<ul><li><p>useEffect</p>

<blockquote>
  <p>类似于componentDidMount/Update</p>
</blockquote></li>
</ul>



<pre class="prettyprint with-line-number hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-comment line-number">1.</span><span class="hljs-comment">//=&gt;如果dependencies不存在，那么callback每次render都会执行</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">2.</span><span class="hljs-comment">//=&gt;如果dependencies存在，只有当它发生了变化callback才会执行</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">3.</span><span class="hljs-comment">//=&gt;如果dependencies是空数组，只有第一次渲染执行一次</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">4.</span>useEffect(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
</div><div class="hljs-line"><span class="hljs-comment line-number">5.</span>    <span class="hljs-comment">// do soming</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">6.</span>    <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-params">()</span>=&gt;</span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">7.</span>        <span class="hljs-comment">// componentWillUnmount</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">8.</span>    }
</div><div class="hljs-line"><span class="hljs-comment line-number">9.</span>}, [dependencies]);
</div></code></pre>

<p>原理：</p>



<pre class="prettyprint with-line-number hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-comment line-number">1.</span><span class="hljs-keyword">let</span> prevDependencies;
</div><div class="hljs-line"><span class="hljs-comment line-number">2.</span><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">useEffect</span>(<span class="hljs-params">callback, dependencies</span>) </span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">3.</span>  <span class="hljs-keyword">const</span> isChanged = dependencies
</div><div class="hljs-line"><span class="hljs-comment line-number">4.</span>    ? dependencies.some(<span class="hljs-function">(<span class="hljs-params">item,index</span>) =&gt;</span> item === prevDependencies[index])
</div><div class="hljs-line"><span class="hljs-comment line-number">5.</span>    : <span class="hljs-literal">true</span>;
</div><div class="hljs-line"><span class="hljs-comment line-number">6.</span>  <span class="hljs-comment">/*如果dependencies不存在，或者dependencies有变化*/</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">7.</span>  <span class="hljs-keyword">if</span> (!dependencies || isChanged) {
</div><div class="hljs-line"><span class="hljs-comment line-number">8.</span>    callback();
</div><div class="hljs-line"><span class="hljs-comment line-number">9.</span>    prevDependencies = dependencies;
</div><div class="hljs-line"><span class="hljs-comment line-number">10.</span>  }
</div><div class="hljs-line"><span class="hljs-comment line-number">11.</span>}
</div></code></pre>

<ul><li><p>useReducer</p></li>
</ul>



<pre class="prettyprint with-line-number hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-comment line-number">1.</span><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">reducer</span>(<span class="hljs-params">state,action</span>)</span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">2.</span>    <span class="hljs-keyword">switch</span>(action.type){
</div><div class="hljs-line"><span class="hljs-comment line-number">3.</span>        <span class="hljs-keyword">case</span> <span class="hljs-string">'ADD'</span>:
</div><div class="hljs-line"><span class="hljs-comment line-number">4.</span>            <span class="hljs-keyword">return</span> {<span class="hljs-attr">count</span>:state.count+<span class="hljs-number">1</span>}
</div><div class="hljs-line"><span class="hljs-comment line-number">5.</span>        <span class="hljs-keyword">default</span>:
</div><div class="hljs-line"><span class="hljs-comment line-number">6.</span>            <span class="hljs-keyword">return</span> {<span class="hljs-attr">count</span>:state.count<span class="hljs-number">-1</span>}
</div><div class="hljs-line"><span class="hljs-comment line-number">7.</span>    }
</div><div class="hljs-line"><span class="hljs-comment line-number">8.</span>}
</div><div class="hljs-line"><span class="hljs-comment line-number">9.</span><wbr>
</div><div class="hljs-line"><span class="hljs-comment line-number">10.</span><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Count</span>()</span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">11.</span>    <span class="hljs-keyword">const</span> [state,dispatch]=useReducer(reducer,{<span class="hljs-attr">count</span>:<span class="hljs-number">10</span>});
</div><div class="hljs-line"><span class="hljs-comment line-number">12.</span>    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;&gt;</span></span>
</div><div class="hljs-line"><span class="hljs-comment line-number">13.</span><span class="xml">        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{state.count}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
</div><div class="hljs-line"><span class="hljs-comment line-number">14.</span><span class="xml">        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{ev</span>=&gt;</span>{</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">15.</span><span class="xml">            dispatch({</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">16.</span><span class="xml">                type:'ADD'</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">17.</span><span class="xml">            })</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">18.</span><span class="xml">        }}&gt;+<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
</div><div class="hljs-line"><span class="hljs-comment line-number">19.</span><span class="xml">        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{ev</span>=&gt;</span>{</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">20.</span><span class="xml">            dispatch({</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">21.</span><span class="xml">                type:'MINUS'</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">22.</span><span class="xml">            })</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">23.</span><span class="xml">        }}&gt;-<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
</div><div class="hljs-line"><span class="hljs-comment line-number">24.</span><span class="xml">    <span class="hljs-tag">&lt;/&gt;</span></span>
</div><div class="hljs-line"><span class="hljs-comment line-number">25.</span><span class="xml">}</span>
</div></code></pre>

<ul><li><p>createRef / useRef </p></li>
</ul>



<pre class="prettyprint with-line-number hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-comment line-number">1.</span><span class="hljs-keyword">let</span> prev;
</div><div class="hljs-line"><span class="hljs-comment line-number">2.</span><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Demo</span>(<span class="hljs-params"></span>)</span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">3.</span>    <span class="hljs-keyword">const</span> inputRef = createRef(); <span class="hljs-comment">//=&gt;{current:xxx}</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">4.</span>    <span class="hljs-comment">//=&gt;每一次视图渲染都会重新生成一个REF（和上一次的不相等：使用useRef进行优化</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">5.</span>    <span class="hljs-comment">//console.log(prev===inputRef); //=&gt;false</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">6.</span>    prev=inputRef;
</div><div class="hljs-line"><span class="hljs-comment line-number">7.</span>    <span class="hljs-keyword">return</span> &lt;&gt;
</div><div class="hljs-line"><span class="hljs-comment line-number">8.</span>        &lt;input ref={inputRef}&gt;
</div><div class="hljs-line"><span class="hljs-comment line-number">9.</span>        &lt;button onClick={ev=&gt;{
</div><div class="hljs-line"><span class="hljs-comment line-number">10.</span>            inputRef.current.focus();
</div><div class="hljs-line"><span class="hljs-comment line-number">11.</span>        }}&gt;聚焦&lt;/button&gt;
</div><div class="hljs-line"><span class="hljs-comment line-number">12.</span>    &lt;/&gt;
</div><div class="hljs-line"><span class="hljs-comment line-number">13.</span>}
</div></code></pre>



<h3 id="dom-diff">DOM DIFF</h3>

<blockquote>
  <p>通过JS层面的计算（逐层比对虚拟DOM对象），生成patch对象（即补丁对象），然后对补丁进行解析和重新渲染</p>
</blockquote>

<p><strong>对树进行分层比较，两棵树只会对同一层次的节点进行比较（不会跨节点比较）</strong></p>



<p><img longdesc="./1572193159062.png" alt="Alt text" title="" type="image/png" src="" class=""></p>

<p>React 只会简单的考虑同层级节点的位置变换，而对于不同层级的节点，只有创建和删除操作</p>



<p><img longdesc="./1572193209775.png" alt="Alt text" title="" type="image/png" src="" class=""></p>

<p>可以处理同级节点顺序的改变</p>

<ul><li><p>每一层级进行对比的计算法则：深度优先遍历</p></li>
<li><p>节点类型相同，看属性是否相同，如果不同，则产生属性的补丁包 {type:’ATTRS’,attrs:{class:’BB’}}</p></li>
<li><p>新的DOM节点不存在，被删除了 {type:’REMOVE’,index:xxx}</p></li>
<li><p>节点类型不相同，直接替换即可 {type:’REPLACE’,newNode:xxx}</p></li>
<li><p>文本的内容进行变化 {type:’TEXT’,text:xxx}</p></li>
<li><p>…</p></li>
</ul>



<pre class="prettyprint with-line-number hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-comment line-number">1.</span><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">diff</span>(<span class="hljs-params">oldTree,newTree</span>)</span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">2.</span>    <span class="hljs-keyword">let</span> patchs = {}; <span class="hljs-comment">//=&gt;补丁包 按照层级放置补丁包 {1:[],2:[]}</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">3.</span>    <span class="hljs-keyword">let</span> index = <span class="hljs-number">0</span>; <span class="hljs-comment">//=&gt;比较的层级</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">4.</span>    <span class="hljs-comment">//=&gt;递归树，比较后的结果放到补丁包</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">5.</span>    walk(oldTree,newTree,index,patchs);
</div><div class="hljs-line"><span class="hljs-comment line-number">6.</span>    <span class="hljs-keyword">return</span> patchs;
</div><div class="hljs-line"><span class="hljs-comment line-number">7.</span>}
</div><div class="hljs-line"><span class="hljs-comment line-number">8.</span><wbr>
</div><div class="hljs-line"><span class="hljs-comment line-number">9.</span><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">walk</span>(<span class="hljs-params">oldNode,newNode,index,patchs</span>)</span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">10.</span>    <span class="hljs-keyword">let</span> currentPatch={};
</div><div class="hljs-line"><span class="hljs-comment line-number">11.</span>    <span class="hljs-keyword">if</span>(!newNode){
</div><div class="hljs-line"><span class="hljs-comment line-number">12.</span>        <span class="hljs-comment">//=&gt;新元素不存在，代表删除</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">13.</span>        currentPatch.push({
</div><div class="hljs-line"><span class="hljs-comment line-number">14.</span>            <span class="hljs-attr">type</span>:<span class="hljs-string">'EMOVE'</span>,
</div><div class="hljs-line"><span class="hljs-comment line-number">15.</span>            index
</div><div class="hljs-line"><span class="hljs-comment line-number">16.</span>        });
</div><div class="hljs-line"><span class="hljs-comment line-number">17.</span>    }<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> oldNode===<span class="hljs-string">"string"</span>&amp;&amp;<span class="hljs-keyword">typeof</span> newNode===<span class="hljs-string">"string"</span>){
</div><div class="hljs-line"><span class="hljs-comment line-number">18.</span>        <span class="hljs-comment">//=&gt;如果是文本，判断文本是否改变 </span>
</div><div class="hljs-line"><span class="hljs-comment line-number">19.</span>        <span class="hljs-keyword">if</span>(oldNode!==newNode){
</div><div class="hljs-line"><span class="hljs-comment line-number">20.</span>            currentPatch.push({
</div><div class="hljs-line"><span class="hljs-comment line-number">21.</span>                <span class="hljs-attr">type</span>:<span class="hljs-string">'TEXT'</span>,
</div><div class="hljs-line"><span class="hljs-comment line-number">22.</span>                <span class="hljs-attr">text</span>:newNode
</div><div class="hljs-line"><span class="hljs-comment line-number">23.</span>            });
</div><div class="hljs-line"><span class="hljs-comment line-number">24.</span>        }
</div><div class="hljs-line"><span class="hljs-comment line-number">25.</span>    }<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(oldNode.type===newNode.type){
</div><div class="hljs-line"><span class="hljs-comment line-number">26.</span>        <span class="hljs-comment">//=&gt;比较属性是否有更改</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">27.</span>        <span class="hljs-keyword">let</span> attrs=diffAttr(oldNode.props,newNode.props);,
</div><div class="hljs-line"><span class="hljs-comment line-number">28.</span>        <span class="hljs-keyword">if</span>(<span class="hljs-built_in">Object</span>.keys(attrs).length&gt;<span class="hljs-number">0</span>){
</div><div class="hljs-line"><span class="hljs-comment line-number">29.</span>            currentPatch.push({
</div><div class="hljs-line"><span class="hljs-comment line-number">30.</span>                <span class="hljs-attr">type</span>:<span class="hljs-string">'ATTRS'</span>,
</div><div class="hljs-line"><span class="hljs-comment line-number">31.</span>                attrs
</div><div class="hljs-line"><span class="hljs-comment line-number">32.</span>            });
</div><div class="hljs-line"><span class="hljs-comment line-number">33.</span>        }
</div><div class="hljs-line"><span class="hljs-comment line-number">34.</span>        <span class="hljs-comment">//=&gt;如果有儿子节点，则遍历儿子</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">35.</span>        diffChildren(
</div><div class="hljs-line"><span class="hljs-comment line-number">36.</span>            oldNode.props.childrren,
</div><div class="hljs-line"><span class="hljs-comment line-number">37.</span>            newNode.props.childrren,
</div><div class="hljs-line"><span class="hljs-comment line-number">38.</span>        index,patchs);
</div><div class="hljs-line"><span class="hljs-comment line-number">39.</span>    }<span class="hljs-keyword">else</span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">40.</span>        <span class="hljs-comment">//=&gt;节点被替换了</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">41.</span>        currentPatch.push({
</div><div class="hljs-line"><span class="hljs-comment line-number">42.</span>            <span class="hljs-attr">type</span>:<span class="hljs-string">'REPACE'</span>,
</div><div class="hljs-line"><span class="hljs-comment line-number">43.</span>            newNode
</div><div class="hljs-line"><span class="hljs-comment line-number">44.</span>        });
</div><div class="hljs-line"><span class="hljs-comment line-number">45.</span>    }
</div><div class="hljs-line"><span class="hljs-comment line-number">46.</span>    <span class="hljs-comment">//=&gt;当前本级查找，确实有补丁，我们放到最外层补丁包中    </span>
</div><div class="hljs-line"><span class="hljs-comment line-number">47.</span>    <span class="hljs-keyword">if</span>(currentPatch.length&gt;<span class="hljs-number">0</span>){
</div><div class="hljs-line"><span class="hljs-comment line-number">48.</span>        patchs[index]=currentPatch;
</div><div class="hljs-line"><span class="hljs-comment line-number">49.</span>    }
</div><div class="hljs-line"><span class="hljs-comment line-number">50.</span>}
</div><div class="hljs-line"><span class="hljs-comment line-number">51.</span><wbr>
</div><div class="hljs-line"><span class="hljs-comment line-number">52.</span><span class="hljs-comment">//=&gt;比较儿子</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">53.</span><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">diffChildren</span>(<span class="hljs-params">oldChildren,newChildren,index,patchs</span>)</span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">54.</span>    oldChildrren.forEach(<span class="hljs-function">(<span class="hljs-params">child,ind</span>)=&gt;</span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">55.</span>        walk(child,newChildren[ind],++index,patchs);
</div><div class="hljs-line"><span class="hljs-comment line-number">56.</span>    })
</div><div class="hljs-line"><span class="hljs-comment line-number">57.</span>}   
</div><div class="hljs-line"><span class="hljs-comment line-number">58.</span><wbr>
</div><div class="hljs-line"><span class="hljs-comment line-number">59.</span><span class="hljs-comment">//=&gt;比较属性，生成补丁包</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">60.</span><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">diffAttr</span>(<span class="hljs-params">oldAttrs,newAttrs</span>)</span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">61.</span>    <span class="hljs-keyword">let</span> patch={};
</div><div class="hljs-line"><span class="hljs-comment line-number">62.</span>    <span class="hljs-keyword">for</span>(ley key <span class="hljs-keyword">in</span> oldAttrs){
</div><div class="hljs-line"><span class="hljs-comment line-number">63.</span>        <span class="hljs-comment">//=&gt;属性不一样（可能是把老的中某个删除了，这样获取的结果可能是undefined）</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">64.</span>        <span class="hljs-keyword">if</span>(oldAttrs[key]!==newAttrs[key]){
</div><div class="hljs-line"><span class="hljs-comment line-number">65.</span>            patch[key]=newAttrs[key];
</div><div class="hljs-line"><span class="hljs-comment line-number">66.</span>        }
</div><div class="hljs-line"><span class="hljs-comment line-number">67.</span>    }
</div><div class="hljs-line"><span class="hljs-comment line-number">68.</span>    <span class="hljs-keyword">for</span>(ley key <span class="hljs-keyword">in</span> newAttrs){
</div><div class="hljs-line"><span class="hljs-comment line-number">69.</span>        <span class="hljs-comment">//=&gt;看老的节点中是否有这样一个属性（没有就是新增）</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">70.</span>        <span class="hljs-keyword">if</span>(!oldAttrs.hasOwnProperty(key)){
</div><div class="hljs-line"><span class="hljs-comment line-number">71.</span>            patch[key]=newAttrs[key];
</div><div class="hljs-line"><span class="hljs-comment line-number">72.</span>        }
</div><div class="hljs-line"><span class="hljs-comment line-number">73.</span>    }
</div><div class="hljs-line"><span class="hljs-comment line-number">74.</span>    <span class="hljs-keyword">return</span> patch;
</div><div class="hljs-line"><span class="hljs-comment line-number">75.</span>}
</div></code></pre>

<p>根据补丁重新渲染</p>



<pre class="prettyprint with-line-number hljs-dark"><code class="language-javascript hljs"><div class="hljs-line"><span class="hljs-comment line-number">1.</span><span class="hljs-keyword">let</span> patchs=diff(xxx,xxx); <span class="hljs-comment">//=&gt;两个虚拟DOM</span>
</div><div class="hljs-line"><span class="hljs-comment line-number">2.</span><span class="hljs-keyword">let</span> node;
</div><div class="hljs-line"><span class="hljs-comment line-number">3.</span><span class="hljs-keyword">let</span> index=<span class="hljs-number">0</span>;
</div><div class="hljs-line"><span class="hljs-comment line-number">4.</span><wbr>
</div><div class="hljs-line"><span class="hljs-comment line-number">5.</span>walk(node);
</div><div class="hljs-line"><span class="hljs-comment line-number">6.</span><wbr>
</div><div class="hljs-line"><span class="hljs-comment line-number">7.</span>functon walk(node){
</div><div class="hljs-line"><span class="hljs-comment line-number">8.</span>    <span class="hljs-keyword">let</span> currentPatch=patches[index++];
</div><div class="hljs-line"><span class="hljs-comment line-number">9.</span>    <span class="hljs-keyword">let</span> cildNodes=node.childNodes;
</div><div class="hljs-line"><span class="hljs-comment line-number">10.</span>    cildNodes.forEach(<span class="hljs-function"><span class="hljs-params">child</span>=&gt;</span>walk(child));
</div><div class="hljs-line"><span class="hljs-comment line-number">11.</span>    <span class="hljs-keyword">if</span>(currentPatch.length&gt;<span class="hljs-number">0</span>){
</div><div class="hljs-line"><span class="hljs-comment line-number">12.</span>        doPatch(node,currentPatch);
</div><div class="hljs-line"><span class="hljs-comment line-number">13.</span>    }
</div><div class="hljs-line"><span class="hljs-comment line-number">14.</span>}
</div><div class="hljs-line"><span class="hljs-comment line-number">15.</span><wbr>
</div><div class="hljs-line"><span class="hljs-comment line-number">16.</span><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">doPatch</span>(<span class="hljs-params">node,patch</span>)</span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">17.</span>    patchs.forRach(<span class="hljs-function">(<span class="hljs-params">item,index</span>)=&gt;</span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">18.</span>        <span class="hljs-keyword">switch</span>(patch.type){
</div><div class="hljs-line"><span class="hljs-comment line-number">19.</span>            <span class="hljs-keyword">case</span> <span class="hljs-string">'ATTRS'</span>:
</div><div class="hljs-line"><span class="hljs-comment line-number">20.</span>                <span class="hljs-keyword">for</span>(<span class="hljs-keyword">let</span> key <span class="hljs-keyword">in</span> patch.attrs){
</div><div class="hljs-line"><span class="hljs-comment line-number">21.</span>                    <span class="hljs-keyword">let</span> val=patch.attrs[key];
</div><div class="hljs-line"><span class="hljs-comment line-number">22.</span>                    <span class="hljs-keyword">if</span>(val){
</div><div class="hljs-line"><span class="hljs-comment line-number">23.</span>                        setAttr(node,key,val);
</div><div class="hljs-line"><span class="hljs-comment line-number">24.</span>                    }<span class="hljs-keyword">else</span>{
</div><div class="hljs-line"><span class="hljs-comment line-number">25.</span>                        node.removeAttribute(key)
</div><div class="hljs-line"><span class="hljs-comment line-number">26.</span>                    }
</div><div class="hljs-line"><span class="hljs-comment line-number">27.</span>                }
</div><div class="hljs-line"><span class="hljs-comment line-number">28.</span>                <span class="hljs-keyword">break</span>;
</div><div class="hljs-line"><span class="hljs-comment line-number">29.</span>            <span class="hljs-keyword">case</span> <span class="hljs-string">'TEXT'</span>:
</div><div class="hljs-line"><span class="hljs-comment line-number">30.</span>                node.textContent=patch.text;
</div><div class="hljs-line"><span class="hljs-comment line-number">31.</span>                <span class="hljs-keyword">break</span>;
</div><div class="hljs-line"><span class="hljs-comment line-number">32.</span>            <span class="hljs-keyword">case</span> <span class="hljs-string">'REPLACE'</span>:
</div><div class="hljs-line"><span class="hljs-comment line-number">33.</span>                <span class="hljs-keyword">let</span> newNode=(patch.newNode <span class="hljs-keyword">instanceof</span> Element)?render(patch.newNode):<span class="hljs-built_in">document</span>.createTextNode(patch.newNode);
</div><div class="hljs-line"><span class="hljs-comment line-number">34.</span>                node.parentNode.replaceChild(newNode,node);
</div><div class="hljs-line"><span class="hljs-comment line-number">35.</span>                <span class="hljs-keyword">break</span>;
</div><div class="hljs-line"><span class="hljs-comment line-number">36.</span>            <span class="hljs-keyword">case</span> <span class="hljs-string">'REMOVE'</span>:
</div><div class="hljs-line"><span class="hljs-comment line-number">37.</span>                node.parentNode.removeChild(node);
</div><div class="hljs-line"><span class="hljs-comment line-number">38.</span>                <span class="hljs-keyword">break</span>;
</div><div class="hljs-line"><span class="hljs-comment line-number">39.</span>        }
</div><div class="hljs-line"><span class="hljs-comment line-number">40.</span>    })  
</div><div class="hljs-line"><span class="hljs-comment line-number">41.</span>}
</div><div class="hljs-line"><span class="hljs-comment line-number">42.</span><wbr>
</div><div class="hljs-line"><span class="hljs-comment line-number">43.</span><wbr>
</div><div class="hljs-line"><span class="hljs-comment line-number">44.</span><wbr>
</div><div class="hljs-line"><span class="hljs-comment line-number">45.</span><wbr>
</div><div class="hljs-line"><span class="hljs-comment line-number">46.</span><wbr>
</div></code></pre></div></body></html>